#include "LecteurFonction.h"


 LecteurFonction::LecteurFonction(LecteurSymbole * ls)
    : Lecteur::Lecteur(ls)
 {
	testerSymCour("fonction");
	arbre = declFonction();
 }

 Noeud* LecteurFonction::declFonction() // <decl_fonction> ::= fonction <variable> (<variable>{,<variable>}) = <seqInst>
 {
     int i = 0;
 	Noeud* noeud;
 	sauterSymCour("fonction");
 	testerSymCour("<VARIABLE>");

 	Symbole s = ls->getSymCour();
 	nom = s.getChaine();
 	ls->suivant();
 	sauterSymCour("(");
 	testerSymCour("<VARIABLE>");
 	param.push_back( ts.chercheAjoute( ls->getSymCour() ) );
 	i++;
 	ls->suivant();
 	while(ls->getSymCour() == ",")
 	{
 		sauterSymCour(",");
 		testerSymCour("<VARIABLE>");
 		param.push_back( ts.chercheAjoute( ls->getSymCour() ) );
 		ls->suivant();
 		i++;
 	}
 	sauterSymCour(")");
 	sauterSymCour("{");
 	NoeudSeqInst* n = new NoeudSeqInst();

 	if(ls->getSymCour() == "retourner")
 	{
 	    sauterSymCour("retourner");
 	    noeud = expression();
        n->ajouteInstruction(noeud);
        sauterSymCour(";");
 	}
 	else
 	{
 	    noeud = seqInst();
        n->ajouteInstruction(noeud);

        sauterSymCour("retourner");
        noeud = expression();
        n->ajouteInstruction(noeud);
        sauterSymCour(";");
 	}

 	sauterSymCour("}");
 	nbParam = i;
 	cout << "fin decl fonction" << endl;
 	return n;

 }



 ///////////////////////////////*******************////////////////////////////////
 //                           Fonctions complémentaires                          //
 ///////////////////////////////*******************////////////////////////////////

////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
Noeud* LecteurFonction::inst() {
// <inst>	::= <affectation> | <instSi> | <instTq> | <instRepeter>

	if ( ls->getSymCour() == "si" )
		return instSi();
	else if ( ls->getSymCour() == "tantque" )
		return instTq();
	else if ( ls->getSymCour() == "repeter" )
		return instRepeter();
	else if ( ls->getSymCour() == "pour" )
		return instPour();
	else if ( ls->getSymCour() == "lire" )
		return instLire();
	else if ( ls->getSymCour() == "ecrire" )
		return instEcrire();
    else if ( ls->getSymCour() == "retourner" )
            return instRetourner();
    else
		return affectation();
}

////////////////////////////////////////////////////////////////////////////////


Noeud* LecteurFonction::instRetourner()
{
    sauterSymCour("retourner");
    Noeud* exp = expression();
    return exp;
}
 ////////////////////////////////////////////////////////////////////////////////

 Noeud* LecteurFonction::getArbre ()
 {
     return arbre;
 }

 vector<SymboleValue*> & LecteurFonction::getParam()
 {
     return param;
 }


string LecteurFonction::getCode(int indent)
{
    string s;
    Multype* m = arbre->getValeur();
    if( typeid (*m) == typeid(TypeInt) )
        s = "int ";
    else if( typeid (*m) == typeid(TypeFloat) )
        s = "float ";
    else if( typeid (*m) == typeid(TypeBool) )
        s = "bool ";
    else if( typeid (*m) == typeid(TypeString) )
        s = "chaine ";

    s += nom;
    s+= " ( " ;
    for (int i = 0; i < nbParam; i++)
    {
            SymboleValue* symb = dynamic_cast<SymboleValue*> (param[i]);
            s += symb->getChaine();
            if(i != (param.size() -1) )
                s += " , ";
    }
    s += " ) \n { \n";
    s += arbre->getCode(indent);
    s+= " \n } ";

    return s;
}
